import urllib
from cPickle import dump
from cPickle import load
from xml.dom import minidom


""" Class Constants """
GOOGLE_WEATHER_URL   = 'http://www.google.com/ig/api?weather=%s&hl=%s'
GOOGLE_COUNTRIES_URL = 'http://www.google.com/ig/countries?output=xml&hl=%s'
GOOGLE_CITIES_URL    = 'http://www.google.com/ig/cities?output=xml&country=%s&hl=%s'
LANGUAGE             = 'en'
ISO_CODE             = 'iso_code'
NAME_TAG             = 'name'

class WeatherFetcher:
    '''
    This class acts as the Internet data base fetcher for the application.
    Allows 2 modes of operation - 
            1. Fetch a new data base from the web.
            2. Use a local DB (an old DB that was fetched from the WEB)
    '''
    
    def __init__(self):
        '''
        Constructor
        '''
        self.weather_reports = {}
        pass

    
    def get_countries_list(self):
        """
        
        Returns a list of countries from Google weather
        
        @return: 
          countries: a list of elements). 
                     Each element is a dictionary with NAME_TAG and 'iso_code' keys. 
        """
        url = GOOGLE_COUNTRIES_URL % (LANGUAGE)
  
        xml_response = urllib.urlopen(url).read()
        dom = minidom.parseString(xml_response)  
        c_dom = dom.getElementsByTagName('country')
        
        countries = {}
        
        for country_dom in c_dom:
            name = country_dom.getElementsByTagName(NAME_TAG)[0].getAttribute('data')
            countries[name] = country_dom.getElementsByTagName(ISO_CODE)[0].getAttribute('data')
            
        """ Bug fix in the API """
        countries["United States"] = "USA"
        
        dom.unlink()
        return countries
    
    
    def get_cities_list(self,country_code):
        """
        Returns the list of cities of a given country
        
        @param 
          country_code: code of the country.
         
        @return: 
          cities: a list of cities of the country code.
        """
        cities = []
         
        url = GOOGLE_CITIES_URL % (country_code,LANGUAGE)
        xml_response = urllib.urlopen(url).read()
        dom = minidom.parseString(xml_response)
    
        c_dom = dom.getElementsByTagName('city')    
        for city_dom in c_dom:
            cities.append(city_dom.getElementsByTagName(NAME_TAG)[0].getAttribute('data'))
        
        dom.unlink()
        return cities
    
      
    def fetch_weather(self, countries_name):
        """ 
        
        Get all of the weather data for a specific country. 
        
        @param 
            country_code: The name of the country that the weather is for.
        
        @return:
            The weather forecast for the next 3 days on all it's cities.
        
        """    
        c_file = open(countries_name, 'r');
        for country_title in c_file : 
            # Get the cities of each country
            data = country_title.split(",");
            country = data[0]
            try:
                cities = self.get_cities_list(country)
            except:
                continue
            
            # For each city, pull weather report        
            for city in cities:
                try : 
                    self.weather_reports[(city + "," + country)] = self.get_city_weather(city+ "," + country)
                except:
                    #print ("Error in xml for country : " + country + ", " + city)
                    continue

        return
    
    def convert_f_to_c(self,temp_f):
        return ((float(5)/float(9))* float( temp_f - 32))

    def get_city_weather(self,city_code):
        """
        returns a city's weather.
        @param city_code: The data base code for the city. 
        """
        
        url = GOOGLE_WEATHER_URL % (city_code,LANGUAGE)
        
        xml_response = urllib.urlopen(url).read()
        dom = minidom.parseString(xml_response)
       
        # Represents a country forecast
        forecast = []
        cond_now = {}
        
        cond_now_dom = dom.getElementsByTagName('current_conditions')
        cond_now["condition"] = str(cond_now_dom[0].getElementsByTagName("condition")[0].getAttribute('data'))
        cond_now["temp_c"] = int(cond_now_dom[0].getElementsByTagName("temp_c")[0].getAttribute('data'))
        cond_now["humidity"] = str(cond_now_dom[0].getElementsByTagName("humidity")[0].getAttribute('data'))
             
        # Save the current condition
        forecast.append(cond_now)
            
        forecast_dom = dom.getElementsByTagName('forecast_conditions')
        tags = ('day_of_week','high','low','condition')
        for f_cast in forecast_dom:
            cur_forecast = {}
            for tag in tags:
                cur_forecast[tag] = str(f_cast.getElementsByTagName(tag)[0].getAttribute('data'))
                if (('low' == tag) or ('high' == tag)):
                    cur_forecast[tag] = int(self.convert_f_to_c(int(cur_forecast[tag])))
            forecast.append(cur_forecast)
        
        return forecast
    
    
    def dump_pools_to_file(self, fname='weatherdata.txt'):
        """
        Save the weather data to files, in DUMP mode.
        """
        fp = open(fname, 'wb')
        dump(self.weather_reports,fp)
        fp.close()


    def load_pools_from_dump_file(self, fname='weatherdata.txt'):
        """
        Load the weather data from file which is saved in dump mode.
        """
        fp = open(fname, 'rb')
        self.weather_reports = load(fp)
        fp.close()